home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / oleo130s.zip / OLEO130S.TAR / oleo-1.3 / help.c < prev    next >
C/C++ Source or Header  |  1993-03-30  |  8KB  |  353 lines

  1. /*    Copyright (C) 1993 Free Software Foundation, Inc.
  2.  
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2, or (at your option)
  6. any later version.
  7.  
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. GNU General Public License for more details.
  12.  
  13. You should have received a copy of the GNU General Public License
  14. along with this software; see the file COPYING.  If not, write to
  15. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  16.  
  17. #include "global.h"
  18. #include "cmd.h"
  19. #include "key.h"
  20. #include "info.h"
  21. #include "forminfo.h"
  22. #include "help.h"
  23. #include "key.h"
  24. #include "io-utils.h"
  25.  
  26. #ifndef alloca
  27. #ifdef __GNUC__
  28. #define alloca __builtin_alloca
  29. #else /* __GNUC__ not defined.  */
  30. #if HAVE_ALLOCA_H
  31. #include <alloca.h>
  32. #else /* not HAVE_ALLOCA_H */
  33. #if defined (MSDOS) && !defined (__TURBOC__)
  34. #include <malloc.h>
  35. #else /* not MSDOS, or __TURBOC__ */
  36. #if defined(_AIX)
  37. #include <malloc.h>
  38. #pragma alloca
  39. #endif /* not _AIX */
  40. #endif /* not MSDOS, or __TURBOC__ */
  41. #endif /* not HAVE_ALLOCA_H */
  42. #endif /* __GNUC__ not defined.  */
  43. #endif /* alloca not defined.  */
  44.  
  45.  
  46.  
  47. /* This reads one info buffer, writing another.  On each line,  
  48.  * occurences of [COMMAND] are replaced with keysequence names,
  49.  * if COMMAND is bound.
  50.  */
  51.  
  52. #ifdef __STDC__
  53. void
  54. expand_help_msg (struct info_buffer * out, struct info_buffer * in)
  55. #else
  56. void
  57. expand_help_msg (out, in)
  58.      struct info_buffer * out;
  59.      struct info_buffer * in;
  60. #endif
  61. {
  62.   int x;
  63.   struct line line;
  64.   struct line seq_buf;
  65.   int out_offset;
  66.   int rel_map = cur_keymap;
  67.  
  68.   if (the_cmd_frame->cmd && (the_cmd_arg.style == &keyseq_style))
  69.     rel_map = the_cmd_arg.val.key.cmd.code;
  70.  
  71.   print_info (out, "");
  72.   out_offset = out->len;
  73.   out->len += in->len;
  74.   out->text = (char **)ck_remalloc (out->text, out->len * sizeof (char *));
  75.   init_line (&line);
  76.   init_line (&seq_buf);
  77.   for (x = 0; x < in->len; ++x)
  78.     {
  79.       char * next_burst = in->text[x];
  80.       char * end_burst = index (next_burst, '[');
  81.       set_line (&line, "");
  82.       set_line (&seq_buf, "");
  83.       while (end_burst)
  84.     {
  85.       char * fn_start = end_burst + 1;
  86.       char * fn_end = index (fn_start, ']');
  87.       int vec;
  88.       struct cmd_func * cmd;
  89.       if (fn_end && (*fn_start == '[') && fn_end[1] == ']')
  90.         {
  91.           int map = map_idn (fn_start + 1, fn_end - fn_start - 1);
  92.           if (map < 0)
  93.         map = map_id ("universal");
  94.           rel_map = map;
  95.           catn_line (&line, next_burst, end_burst - next_burst);
  96.           next_burst = fn_end + 2;
  97.           end_burst = index (next_burst, '[');
  98.         }
  99.       else if (   fn_end
  100.            && !find_function (&vec, &cmd, fn_start, fn_end - fn_start))
  101.         {
  102.           if (search_map_for_cmd (&seq_buf, rel_map, vec,
  103.                       cmd - the_funcs[vec])) 
  104.         {
  105.           catn_line (&line, next_burst, end_burst - next_burst);
  106.           catn_line (&line, seq_buf.buf, strlen (seq_buf.buf));
  107.           set_line (&seq_buf, "");
  108.           next_burst = fn_end + 1;
  109.           end_burst = index (next_burst, '[');
  110.         }
  111.           else
  112.         {
  113.           catn_line (&line, "M-x ", 4);
  114.           catn_line (&line, fn_start, fn_end - fn_start);
  115.           next_burst = fn_end + 1;
  116.           end_burst = index (next_burst, '[');
  117.         }
  118.         }
  119.       else if (fn_end)
  120.         end_burst = index (fn_end + 1, '[');
  121.     }
  122.       catn_line (&line, next_burst, strlen(next_burst));
  123.       out->text[x + out_offset] = line.buf;
  124.       init_line (&line);
  125.     }
  126.   free_line (&seq_buf);
  127.   free_line (&line);
  128. }
  129.  
  130.  
  131.  
  132.  
  133. #ifdef __STDC__
  134. void
  135. describe_function (char * name)
  136. #else
  137. void
  138. describe_function (name)
  139.      char * name;
  140. #endif
  141. {
  142.   int vector;
  143.   struct cmd_func * cmd;
  144.   if (!(   !find_function (&vector, &cmd, name, strlen(name))
  145.     && cmd->func_doc))
  146.     io_error_msg ("%s is not a function.", name); /* no return */
  147.   
  148.   {
  149.     struct info_buffer * ib_disp = find_or_make_info ("help-buffer");
  150.     clear_info (ib_disp);
  151.     print_info (ib_disp, "");
  152.     print_info (ib_disp, "%s", name);
  153.     {
  154.       struct info_buffer ib;
  155.       for (ib.len = 0; cmd->func_doc[ib.len]; ++ib.len) ;
  156.       ib.text = cmd->func_doc;
  157.       ib.name = name;
  158.       expand_help_msg (ib_disp, &ib);
  159.     }
  160.   }
  161.  
  162.   {
  163.     static char buf[] = "{view-info help-buffer}";
  164.     execute_as_macro (buf);
  165.   }
  166. }
  167.  
  168.  
  169.  
  170. #ifdef __STDC__
  171. void
  172. brief_describe_key (struct key_sequence * keyseq)
  173. #else
  174. void
  175. brief_describe_key (keyseq)
  176.      struct key_sequence * keyseq;
  177. #endif
  178. {
  179.   if (keyseq->cmd.vector < 0 && keyseq->cmd.code < 0)
  180.     io_info_msg ("%s is unbound", keyseq->keys->buf);
  181.   else
  182.     io_info_msg ("%s --> %s", keyseq->keys->buf,
  183.          the_funcs[keyseq->cmd.vector][keyseq->cmd.code].func_name);
  184. }
  185.  
  186. #ifdef __STDC__
  187. void
  188. describe_key (struct key_sequence * keyseq)
  189. #else
  190. void
  191. describe_key (keyseq)
  192.      struct key_sequence * keyseq;
  193. #endif
  194. {
  195.   if (keyseq->cmd.vector < 0 && keyseq->cmd.code < 0)
  196.     io_info_msg ("%s is unbound", keyseq->keys->buf);
  197.   else if (keyseq->cmd.vector < 0)
  198.     io_info_msg ("%s is a prefix leading to the keymap `%s'.",
  199.          keyseq->keys->buf, map_names[keyseq->cmd.code]);
  200.   else
  201.     describe_function
  202.       (the_funcs[keyseq->cmd.vector][keyseq->cmd.code].func_name); 
  203. }
  204.  
  205.  
  206. #ifdef __STDC__
  207. void
  208. where_is (char * name)
  209. #else
  210. void
  211. where_is (name)
  212. char * name;
  213. #endif
  214. {
  215.   struct line seqname;
  216.   int vec;
  217.   int code;
  218.   struct cmd_func * cmd;
  219.   
  220.   if (!find_function (&vec, &cmd, name, strlen(name)))
  221.     code = cmd - the_funcs[vec];
  222.   else if (map_id (name) >= 0)
  223.     {
  224.       code = map_id (name);
  225.       vec = -1;
  226.     }
  227.   else
  228.     io_error_msg ("%s is not a function.", name); /* no return */
  229.   code = cmd - the_funcs[vec];
  230.   init_line (&seqname);
  231.   set_line (&seqname, "");
  232.   
  233.   if (!search_map_for_cmd (&seqname, the_cmd_frame->top_keymap, vec, code))
  234.     io_info_msg ("%s is not on any keys.", name);
  235.   else
  236.     io_info_msg ("%s is bound to %s.", name, seqname.buf);
  237.   
  238.   free_line (&seqname);
  239. }
  240.  
  241.  
  242. /* Help for the context of the current complex command. */
  243.  
  244. #ifdef __STDC__
  245. void
  246. help_with_command (void)
  247. #else
  248. void
  249. help_with_command ()
  250. #endif
  251. {
  252.   if (!the_cmd_frame->cmd)
  253.     io_info_msg ("help-with-command: No command is executing now.");
  254.   describe_function (the_cmd_frame->cmd->func_name);
  255. }
  256.  
  257.  
  258.  
  259.  
  260.  
  261. /* Access to the help messages defined in forminfo.c
  262.  * These include documentation for formula functions and
  263.  * other miscelaneous doc strings.
  264.  *
  265.  * The info message NAME is permanently stored in an info-buffer
  266.  * called _info_NAME
  267.  */
  268.  
  269. #ifdef __STDC__
  270. void
  271. builtin_help (char * name)
  272. #else
  273. void
  274. builtin_help (name)
  275.      char * name;
  276. #endif
  277. {
  278.   char info_name[100];
  279.   struct info_buffer * ib;
  280.  
  281.   if (strlen (name) < sizeof (info_name - 20))
  282.     io_error_msg ("No built in help for %s.", name);
  283.  
  284.   sprintf (info_name, "_info_%s", name);
  285.   ib = find_info (info_name);
  286.  
  287.   if (!ib)
  288.     {
  289.       char ** msg = forminfo_text (name);
  290.       if (!msg)
  291.     {
  292.       msg = (char **)ck_malloc (sizeof (char *) * 2);
  293.       msg[0] = mk_sprintf ("No built in help for %s.", name);
  294.       msg[1] = 0;
  295.     }
  296.       ib = find_or_make_info (info_name);
  297.       ib->len = parray_len (msg);
  298.       ib->text = msg;
  299.     }
  300.  
  301.   {
  302.     char exp_name[200];
  303.     char command[250];
  304.     struct info_buffer * expanded;
  305.     sprintf (exp_name, "_expanded_%s", info_name);
  306.     expanded = find_or_make_info (exp_name);
  307.     clear_info (expanded);
  308.     expand_help_msg (expanded, ib);
  309.     sprintf (command, "{set-info %s}", exp_name);
  310.     execute_as_macro (command);
  311.   }
  312. }
  313.  
  314. #ifdef __STDC__
  315. void
  316. make_wallchart_info (void)
  317. #else
  318. void
  319. make_wallchart_info ()
  320. #endif
  321. {
  322.   struct info_buffer * wc = find_or_make_info ("unexpanded_wallchart");
  323.   struct info_buffer * wc_expanded = find_or_make_info ("wallchart");
  324.   if (wc->len == 0)
  325.     {
  326.       char ** txt = forminfo_text ("keybindings-wallchart");
  327.       if (!txt)
  328.     io_error_msg ("<bug> Wallchart is missing!");
  329.       wc->len = parray_len (txt);
  330.       wc->text = txt;
  331.     }
  332.   clear_info (wc_expanded);
  333.   expand_help_msg (wc_expanded, wc);
  334. }
  335.  
  336.  
  337. #ifdef __STDC__
  338. void
  339. write_info (char * info, FILE * fp)
  340. #else
  341. void
  342. write_info (info, fp)
  343.      char * info;
  344.      FILE * fp;
  345. #endif
  346. {
  347.   struct info_buffer * ib = find_or_make_info (info);
  348.   int x;
  349.   for (x = 0; x < ib->len; ++x)
  350.     fprintf (fp, "%s\n", ib->text[x]);
  351. }
  352.  
  353.